import CryptoJS from 'crypto-js/crypto-js'
import JSEncrypt from 'jsencrypt'
// 外网国密
// import smCrypto from 'sm-crypto'

export default {

  /** **************** 非国密 ****************** */

  /**
    * RSA加密
    * @param {String} plaintext
    * @param {String} publickey
    * (return时对加密串进行特殊字符的转义)
    */
  encryptRSA(plaintext, publickey) {
    const encryptor = new JSEncrypt()
    encryptor.setPublicKey(publickey)
    const ciphertext = encryptor.encrypt(plaintext)
    return encodeURIComponent(ciphertext)
  },

  /**
     * RSA解密
     * @param {String} ciphertext
     * @param {String} privatekey
     */
  decryptRSA(ciphertext, privatekey) {
    const decrptor = new JSEncrypt()
    decrptor.setPrivateKey(privatekey)
    const plaintext = decrptor.decrypt(ciphertext)
    return plaintext
  },

  /**
     * AES加密
     * @param {String} key 密钥：十六进制密钥
     * @param {String} plaintext String或者JSON.stringify(obj)
     * @param {String} iv 十六位随机数
     * @return 加密后的字符串  (可选转为Base64的字符串）
     */
  encryptAES(plaintext, key, iv) {
    const srcs = CryptoJS.enc.Utf8.parse(plaintext)
    const lockKey = CryptoJS.enc.Utf8.parse(key)
    const lockIv = CryptoJS.enc.Utf8.parse(iv)
    const cipher = CryptoJS.AES.encrypt(srcs, lockKey, {
      iv: lockIv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    })
    return cipher.ciphertext.toString().toUpperCase()
    // return CryptoJS.enc.Base64.stringify(cipher.ciphertext)
  },

  /**
     * AES解密
     * @param {String} key 密钥：十六进制密钥
     * @param {String} ciphertext String 目前后端传来Base64的字符串（可选直接加密后的字符串，则需先进行base64转换）
     * @param {String} iv 十六位随机数
     */
  decryptAES(ciphertext, key, iv) {
    const lockKey = CryptoJS.enc.Utf8.parse(key)
    const lockIv = CryptoJS.enc.Utf8.parse(iv)
    const plain = CryptoJS.AES.decrypt(ciphertext, lockKey, {
      iv: lockIv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    })
    const plained = plain.toString(CryptoJS.enc.Utf8)
    return plained.toString()
  },

  /**
     * SHA-256
     * @param {String} text
     */
  encryptSHA256(text) {
    return CryptoJS.SHA256(text).toString()
  },

  /** **************** 国密 ***************** */

  /**
     * SM2生成密钥
     * @returns {object} keypair
     * keypair.privateKey 私钥
     * keypair.publicKey  公钥
     */
  genKeysSM2() {
    // 选择SM2算法加解密模式 加密模式 C1C2C3 : '0', C1C3C2 : '1'
    const cipher = new SM2CipherUtil('1')
    const keypair = cipher.sm2GengenerateKeys()
    return keypair
  },

  /**
     * SM2加密
     * @param {String} plaintext
     * @param {String} publicKey 十六位
     */
  encryptSM2(plaintext, publicKey) {
    const cipher = new SM2CipherUtil('1')
    const ciphertext = cipher.sm2Encrypt(publicKey, plaintext)
    return ciphertext
  },

  /**
     * SM2解密
     * @param {String} ciphertext
     * @param {String} privateKey
     */
  decryptSM2(ciphertext, privateKey) {
    const cipher = new SM2CipherUtil('1')
    const plaintext = cipher.sm2Decrypt(privateKey, ciphertext.toUpperCase())
    return plaintext
  },

  /**
     * SM3
     * @param {String} text
     */
  encryptSM3(text) {
    const sm3 = new SM3Util()
    return sm3.sm3Hash(text)
  },

  /**
     * SM4生成密钥
     * @returns String key
     * keypair.privateKey 私钥
     */
  genKeysSM4() {
    const sm4 = new SM4Util()
    return sm4.getSm4Key()
  },

  /**
     * SM4加密
     * @param {String} plaintext
     * @param {String} key
     */
  encryptSM4(plaintext, key) {
    const sm4 = new SM4Util()
    const ciphertext = sm4.sm4Encrypt(key, plaintext)
    return ciphertext
  },

  /**
     * SM4解密
     * @param {String} ciphertext
     * @param {String} key
     */
  decryptSM4(ciphertext, key) {
    const sm4 = new SM4Util()
    const plaintext = sm4.sm4Decrypt(key, ciphertext)
    return plaintext
  }
}
